<?php
/**
 * Created by IntelliJ IDEA.
 * User: lee
 * Date: 2018/2/5
 * Time: 下午3:15
 */

namespace Biz\service\trade;

use Biz\cache\Coupon as cCoupon;
use Biz\cache\UserBoughtGoods as UserBoughtGoodsCache;
use Biz\model\admin\AdminUser;
use Biz\model\OperateLog as mOperateLog;
use Biz\model\ShopBasicInfo as mShopBasicInfo;
use Biz\model\ShopComments;
use Biz\model\trade\GroupJoinMember as mGroupJoinMember;
use Biz\model\trade\Order as mOrder;
use Biz\model\trade\OrderExcel as mOrderExcel;
use Biz\model\trade\OrderExcelLog as mOrderExcelLog;
use Biz\model\trade\OrderGoods as mOrderGoods;
use Biz\model\trade\OrderMatching as mHhzOrderConfirm;
use Biz\model\trade\OrderOperateLog;
use Biz\model\trade\OrderOperateLog as mOrderOperateLog;
use Biz\model\trade\OrderPackage as mOrderPackage;
use Biz\model\trade\OrderParent as mOrderParent;
use Biz\model\trade\OrderRefund as mOrderRefund;
use Biz\model\trade\OrderRemark;
use Biz\model\trade\OrderRemark as mOrderRemark;
use Biz\model\trade\ShopCourier as mShopCourier;
use Biz\module\Classes\adm\OrderDetail as clsAdmOrderDetail;
use Biz\module\Classes\adm\OrderList;
use Biz\module\Classes\adm\OrderList as clsAdmOrderList;
use Biz\module\Classes\adm\OrderMessage as clsAdmOrderMessage;
use Biz\module\Classes\adm\OrderSearch as clsAdmOrderSearch;
use Biz\module\Classes\mgt\Order as clsMgtOrder;
use Biz\module\Classes\mgt\OrderDetail as mgtOrderDetail;
use Biz\module\Classes\mgt\OrderExcel as clsMgtOrderExcel;
use Biz\module\Classes\mgt\OrderExcel as mgtOrderExcel;
use Biz\module\Classes\mgt\OrderInfo as clsMgtOrderInfo;
use Biz\module\Classes\mgt\OrderMessage as mOrderMessage;
use Biz\module\Classes\mgt\OrderSearch as mgtOrderSearch;
use Biz\module\Classes\Order as clsOrder;
use Biz\module\Classes\OrderDetail as clsOrderDetail;
use Biz\module\Classes\OrderInfo as clsOrderInfo;
use Biz\module\Classes\OrderList as clsOrderList;
use Biz\module\Classes\OrderPackage as clsOrderPackage;
use Biz\module\Classes\OrderRefund as clsOrderRefund;
use Biz\module\Classes\ShopCoupon as clsShopCoupon;
use Biz\module\Packages\CustomerService\SmallEnergy;
use Biz\module\Sys\ErrorConst;
use Biz\module\Sys\ErrorConst as clsErrorConst;
use Biz\pockets\constInterface\ActivityInfo;
use Biz\pockets\serviceTrait\_Async;
use Biz\service\esSearch\Order as searchOrder;
use Biz\service\Event;
use Biz\service\GoodsDetail;
use Biz\service\Group;
use Biz\service\OperateLog as sOperateLog;
use Biz\service\settlement\SettlementTransaction;
use Biz\service\trade\Logistics as sLogistics;
use Biz\service\trade\ShopCourier as sShopCourier;
use Biz\tools\Amount;
use Biz\tools\OrderNo as toolOrderNo;
use Biz\tools\ShopArea as tArea;
use Biz\tools\ThrowException as toolThrowException;
use Doraemon\amqp\Queue;
use Doraemon\model\Member;
use Biz\service\brand\Brand;
use Doraemon\service\search\AdmUserSearch;
use Doraemon\service\SearchAddTag;
use Doraemon\service\User;
use Doraemon\tools\Log as tLog;
use Medoo\Medoo;
/**
 * @deprecated
 */
class Order implements ActivityInfo

{
    use _Async;

    /**
     * 确认订单列表
     * @param $uid 用户uid
     * @param array $submitSku $submit_sku ["sku_id"=>1,"buy_num"=>2] 要结算的sku信息
     * @param $areaCode 地区code（市）
     * @param $source 订单来源 1:购物车 2：立即购买
     * @param int $acceptId 地址簿id
     * @param $skuToken
     * @param $couponId 优惠券id
     * @param $couponVid 领取到的优惠券的唯一编号
     * @param array $sCouponInfo 店铺优惠券信息
     * @param int $mealId 套餐id
     * @param int $useIntegral 是否使用积分
     * @param int $usePacket 是否使用红包
     * @param int $appType app来源
     * @param int $storeId 节选店铺id
     * @param int $isSelfMention 是否店铺自提
     * @param int $activityId 活动id（拼团活动id）
     * @param int $activityType 活动类型
     * @param int $teamJoinId 参团id
     * @return array
     * @throws
     */
    public static function confirmOrderList($uid, array $submitSku, $areaCode, $source, $acceptId = null, $skuToken = null, $couponId = null, $couponVid = null, $sCouponInfo = [], $mealId = null, $useIntegral = 1, $usePacket = 1, $appType = 1, $storeId = 0, $isSelfMention = 0, $activityId = 0, $activityType = 0, $teamJoinId = 0)
    {
        try {
            $result = (new clsOrder())->confirmOrderList($uid, $submitSku, $areaCode, $source, $acceptId, $skuToken, $couponId, $couponVid, $sCouponInfo, $mealId, $useIntegral, $usePacket, $appType, $storeId, $isSelfMention, $activityId, $activityType, $teamJoinId);
            return $result;
        } catch (\Exception $e) {
            $errorArr = [
                'uid' => $uid,
                'submit_sku' => $submitSku,
                'area_Code' => $areaCode,
                'accept_Id' => $acceptId,
                'submit_token' => $skuToken,
                'coupon_Id' => $couponId,
                'coupon_vid' => $couponVid,
                's_coupon_info' => $sCouponInfo,
                'meal_id' => $mealId,
                'use_integral' => $useIntegral,
                'use_packet' => $usePacket,
                'app_type' => $appType,
                'store_id' => $storeId,
                'self_mention' => $isSelfMention,
                'activity_id' => $activityId,
                'activity_type' => $activityType,
                'team_join_id' => $teamJoinId,
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ];
            tLog::warning('获取确认订单信息失败', $errorArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => "获取确认订单信息失败:#date:" . date('YmdHis') . "#params:" . json_encode($errorArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw $e;
        }
    }

    /**
     * 提交订单
     * @param $uid
     * @param $skuToken
     * @param $acceptId 地址簿id
     * @param $messageInfo 店铺留言信息
     * @param $integral 使用积
     * @param $packetAmount 使用红包
     * @param $couponId 优惠券id
     * @param $couponVId 用户获取的优惠券唯一标识
     * @param array $sCouponInfo 店铺优惠券信息
     * @param int $appType app来源
     * @param int $mealId 套餐id
     * @param int $storeId 节选店铺id
     * @param int $isSelfMention 是否店铺自提
     * @param int $activityId 活动id（拼团活动id）
     * @param int $activityType 活动类型
     * @param int $teamJoinId 参团id
     * @return array
     * @throws \Exception
     */
    public static function create($uid, $skuToken, $acceptId, $messageInfo, $integral, $packetAmount, $couponId, $couponVId, $sCouponInfo = [], $appType = 1, $mealId = null, $storeId = 0, $isSelfMention = 0, $activityId = 0, $activityType = 0, $teamJoinId = 0)
    {
        try {
            $result = (new clsOrder())->create($uid, $skuToken, $acceptId, $messageInfo, $integral, $packetAmount, $couponId, $couponVId, $sCouponInfo, $appType, $mealId, $storeId, $isSelfMention, $activityId, $activityType, $teamJoinId);
            return $result;
        } catch (\Exception $e) {
            $errorArr = [
                'uid' => $uid,
                'sku_token' => $skuToken,
                'accept_Id' => $acceptId,
                'message_info' => $messageInfo,
                'integral' => $integral,
                'packet_amount' => $packetAmount,
                'coupon_id' => $couponId,
                'coupon_vid' => $couponVId,
                's_coupon_info' => $sCouponInfo,
                'app_type' => $appType,
                'meal_id' => $mealId,
                'store_id' => $storeId,
                'self_mention' => $isSelfMention,
                'activity_id' => $activityId,
                'activity_type' => $activityType,
                'team_join_id' => $teamJoinId,
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ];
            tLog::warning('提交订单信息失败', $errorArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => "提交订单信息失败:#date:" . date('YmdHis') . "#params:" . json_encode($errorArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw $e;
        }
    }


    /**
     * @param $orderNo
     * @param $payWay
     * @param $payNo
     * @param $payAmount
     * @param $payTime
     *
     * @return
     *
     *
     * @throws \Exception
     */

    public static function afterPaySuccessCallback($orderNo, $payWay, $payNo, $payAmount, $payTime, $payVer = 0)
    {
        $result = [
            'code' => 0,
            'data' => [],
        ];

        $orderInfo = [];
        //支付的信息
        $payData = [
            'pay_way' => $payWay,
            'pay_no' => $payNo,
            'pay_amount' => $payAmount,
            'pay_time' => $payTime
        ];


        //如果是父单，则需要判断父单的状态
        $isParent = toolOrderNo::isParentNo($orderNo);

        try {

            //查询子订单基本信息
            $orderNoList = mOrder::getOrderNoList($orderNo);

            if (empty($orderNoList)) {
                throw new \Exception('订单不存在');
            }

            if ($isParent) {
                $parentInfo = mOrderParent::getOrderParentInfo($orderNo);

                if (empty($parentInfo)) {
                    throw new \Exception('订单不存在');
                }

                if (!empty($parentInfo['pay_way'])) {
                    //不同的交易号，则需要抛出异常
                    if ($parentInfo['pay_no'] != $payNo) {
                        toolThrowException::main(ErrorConst::ERROR_ORDER_PAY_AGAIN_ERROR);
                    } else {
                        return false;
                    }
                }

            } else {
                $orderInfo = mOrder::getOrderInfo($orderNo);

                if (!empty($orderInfo) && $orderInfo['pay_ver'] != $payVer) {
                    throw new \Exception('由于支付序列号对不上，此次支付失败');
                }
            }

            $orderInfoList = mOrder::getOrderInfoList(['order_no' => $orderNoList], [], [], false);

            if (empty($orderInfoList)) {
                throw new \Exception('该订单不可支付，原因：订单不存在');
            }

            //加日志
            tLog::order_paysuccess_info('支付成功后回调查询出订单列表', [
                'order_no' => $orderNo,
                'params' => [
                    'order_no' => $orderNo,
                    'pay_way' => $payWay,
                    'pay_no' => $payNo,
                    'pay_amount' => $payAmount,
                    'pay_time' => $payTime
                ],
                'order_list' => $orderInfoList
            ]);

            //判断订单状态是否可以支持此次支付请求
            foreach ($orderInfoList as $orderInfo) {

                //判断可以支付
                if ($orderInfo['status'] == mOrder::STATUS_NORMAL) {

                    //记录父订单号
                    $orderParentNo = $orderInfo['order_parent_no'];

                    //判断已取消、关闭、删除
                } elseif (in_array($orderInfo['status'], [
                    mOrder::STATUS_CLOSE,
                    mOrder::STATUS_DEL
                ])) {

                    toolThrowException::main(ErrorConst::ERROR_ORDER_IS_CANCEL);

                    //判断不可以支付状态
                } else {

                    if (!empty($orderInfo['pay_way'])) {

                        //不同的交易号，则需要抛出异常
                        if ($orderInfo['pay_no'] != $payNo) {
                            toolThrowException::main(ErrorConst::ERROR_ORDER_PAY_AGAIN_ERROR);
                        } else {

                            return false;

                        }
                    }
                }
            }

            $result = mOrder::action(function () use ($orderNoList, $payData, $isParent, $orderParentNo) {

                unset($payData['pay_amount']);


                //判断是否是父单支付，如果是父单支付，则需要更改父单状态
                if ($isParent && isset($orderParentNo)) {
                    $data = mOrderParent::update(array_merge([
                        'is_can_pay' => mOrderParent::IS_CAN_PAY_NO
                    ], $payData), ['order_parent_no' => $orderParentNo]);

                } else {
                    $data = mOrderParent::update(['is_can_pay' => mOrderParent::IS_CAN_PAY_NO], [
                        'order_parent_no' => $orderParentNo,
                        'is_can_pay' => mOrderParent::IS_CAN_PAY_YES
                    ]);
                }

                $result = mOrder::update(array_merge(['status' => mOrder::STATUS_WAIT_SEND], $payData), [
                    'order_no' => $orderNoList,
                    'status' => mOrder::STATUS_NORMAL
                ]);


                if (is_object($result) && $result->rowCount() != count($orderNoList)) {
                    toolThrowException::main(ErrorConst::ERROR_ORDER_PAIED_ERROR);
                }


                return [
                    'code' => 1,
                    'data' => $orderNoList,
                ];
            });


            if ($result['code'] === 1) {

                $orderInfo = isset($orderInfoList[0]) ? $orderInfoList[0] : [];

                //发送支付成功的事件
                Event::push(Event::ORDER_PAY_SUCCESS, [
                    'uid' => $orderInfo['uid'],
                    'order_no' => $orderNo,
                    'shop_id' => $orderInfo['shop_id'],
                    'order_pno' => $orderParentNo,
                    'order_info_list' => $orderInfoList,
                    'is_pno_pay' => $isParent ? 1 : 0,
                    'pay_amount' => $payAmount,
                    'pay_way' => $payWay,
                    'pay_no' => $payNo,
                    'pay_time' => $payTime,
                    'pay_ver' => $payVer,
                    'uniq_idx' => [
                        'order_no',
                        'event_tag',
                        'pay_no'
                    ]
                ]);


                //拼团回调，需要实时回调
                if ($orderInfo['order_type'] == mOrder::ORDER_TYPE_PING_TUAN) {
                    Group::payGroup($orderInfo['order_no']);
                }

            }


            return $result;

        } catch (\Exception $e) {

            //发送支付失败的事件
            Event::push(Event::ORDER_PAY_FAIL, [
                'order_no' => $orderNo,
                'is_pno_pay' => $isParent ? 1 : 0,
                'e_msg' => $e->getMessage(),
                'now_time' => date('Y-m-d H:i:s'),
                'uniq_idx' => [
                    'order_no',
                    'event_tag',
                    'now_time'
                ]
            ]);


            tLog::order_paysuccess_warning('支付成功后回调出现异常', [
                'order_no' => $orderNo,
                'params' => [
                    'order_no' => $orderNo,
                    'pay_way' => $payWay,
                    'pay_no' => $payNo,
                    'pay_amount' => $payAmount,
                    'pay_time' => $payTime
                ],
                'exception' => [
                    'code' => $e->getCode(),
                    'msg' => $e->getMessage(),
                    'file' => $e->getFile()
                ]
            ]);

            throw $e;
        }


        //无异常
    }


    /**
     * 获取收银台订单信息
     * @param $orderNo
     * @return array 收银台信息
     * @throws \Exception
     */
    public static function getCashierAmount($orderNo)
    {
        $isParentNo = toolOrderNo::isParentNo($orderNo);
        if (!$isParentNo) {//子订单
            $info = mOrder::getOrderInfoFromMaster($orderNo);
            if (!$info || $info['status'] != mOrder::STATUS_NORMAL) {
                tLog::warning('收银台订单支付信息异常', [
                    'order_info' => $info,
                    'order_no' => $orderNo,
                ]);
                if ($info['status'] == mOrder::STATUS_WAIT_SEND) {
                    throw new \Exception('订单已付款', ErrorConst::ERROR_PAY_ORDER_INFO_PAID);
                } else {
                    throw new \Exception('订单已关闭', ErrorConst::ERROR_PAY_ORDER_INFO_UNKNOW);
                }
            }
            $info['shop_ids'] = [$info['shop_id']];
        } else {
            $info = mOrderParent::getOrderParentInfoFromMaster($orderNo);
            if (!$info || !$info['is_can_pay']) {
                tLog::warning('收银台订单支付信息异常', [
                    'order_info' => $info,
                    'order_parent_no' => $orderNo,
                ]);
                if ($info['pay_way']) {
                    throw new \Exception('订单已付款', ErrorConst::ERROR_PAY_ORDER_INFO_PAID);
                } else {
                    throw new \Exception('订单已关闭', ErrorConst::ERROR_PAY_ORDER_INFO_UNKNOW);
                }
            }
            $orderList = mOrder::getOrderInfoList(['order_parent_no' => $orderNo]);
            $info['shop_ids'] = array_column($orderList, 'shop_id');
            $info['consignee_phone'] = $orderList[0]['consignee_phone'];
        }
        $result = [];
        if ($info) {
            $shop_reception_group_ids = SmallEnergy::getShopInfoByShopIds($info['shop_ids'], 'pre_sale_reception_group_id');
            $result = [
                'order_no' => $orderNo,
                'uid' => $info['uid'],
                'consignee_phone' => $info['consignee_phone'],
                'pay_amount' => $info['pay_amount'],
                'buy_num' => $info['buy_num'],
                'paystop_time' => strtotime($info['paystop_time']),
                'shop_reception_group_ids' => $shop_reception_group_ids,
                'pay_ver' => !empty($info['pay_ver']) ? $info['pay_ver'] : 0,
            ];
        }
        return $result;
    }

    /**
     * 商家确认发货
     * @param $orderNo
     * @param $data
     * @param $shopId
     * @throws \Exception
     */
    public static function mgtShipOrderByOrderNo($orderNo, $expressData, $shopId, $courierId, $isMulti = false, $skuIds = '')
    {
        $result = null;
        try {
            $result = clsMgtOrder::shipOrder($orderNo, $expressData, $shopId, $courierId, $isMulti, $skuIds);

            return $result;
        } catch (\Exception $e) {
            tLog::order_OrderStatus_warning($isMulti ? '商家批量发货异常' : '商家确认发货异常', [
                'shop_id' => $shopId,
                'order_no' => $orderNo,
                'order_status_to' => mOrder::STATUS_SEND_OUT,
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);

            if ($isMulti == true) {
                return $result;
            }

            throw $e;

        }

    }

    /**
     * 取消订单
     * @param $orderNo
     * @param int $uid
     * @param bool $isSys
     * @throws \Exception
     *
     */
    public static function cancelOrder($orderNo, $uid = 0, $isSys = false, $reasonId = 0)
    {
        //判断是否父订单
        if (toolOrderNo::isParentNo($orderNo)) {
            throw new \Exception('父订单号不支持订单取消');
        }

        try {

            //查询订单是否可以关闭
            $result = Pay::checkOrderPayStatus($orderNo);

            if ($result === true) {
                throw new \Exception('订单已付款不可取消或关闭');
            }

            $result = mOrder::action(function () use ($orderNo, $uid, $isSys, &$orderInfo, $reasonId) {

                //获取订单信息
                $orderInfo = mOrder::getOrderInfoFromMaster($orderNo);

                //判断订单状态  防止多次取消
                if (!mOrder::checkStatusCanPay($orderInfo['status'])) {
                    throw new \Exception('请核实订单状态');
                }
                $data = [
                    'cancel_time' => date('Y-m-d H:i:s'),
                ];

                //判断是否为系统操作
                if (empty($uid) && $isSys) {
                    $data['cancel_type'] = mOrder::CANCEL_TYPE_SYSTEM;
                    $data['status'] = mOrder::STATUS_CLOSE;
                } else {

                    if ($orderInfo['uid'] != $uid) {
                        throw new \Exception('您没有此订单');
                    }
                    $data['cancel_type'] = mOrder::CANCEL_TYPE_HANDLE;
                    $data['status'] = mOrder::STATUS_CLOSE;
                    $data['cancel_reason'] = $reasonId;
                }

                $orderParentNo = $orderInfo['order_parent_no'];

                //修改订单状态
                $result = mOrder::update($data, ['order_no' => $orderNo]);
                if ($result->rowCount() == 0) {
                    throw new \Exception('状态修改失败');
                }

                //父订单变为不可付款状态
                $payNot = mOrderParent::changeCanPayToNo($orderParentNo);


                //优惠券？？？？？

            });

            if ($result !== false) {

                //取消订单是一个串行操作,需要同一个 Eventid
                $eventId = Event::genUniqId();


                //取消订单成功的事件
                Event::push(Event::ORDER_CANCEL_ORDER_SUCCESS, [
                    'uid' => isset($orderInfo['uid']) ? $orderInfo['uid'] : 0,
                    'order_no' => $orderNo,
                    'is_sys' => (int)$isSys,
                    'reason_id' => $reasonId,
                    'reason_desc' => $reasonId > 0 ? mOrder::$cancelReasonDesc[$reasonId] : '',
                    'uniq_idx' => [
                        'order_no',
                        'event_tag'
                    ]
                ], $eventId);


                if ($orderInfo['integral_amount'] > 0 || $orderInfo['discount_amount'] > 0 || $orderInfo['coupon_amount'] > 0 || $orderInfo['activity_allowance'] > 0 || $orderInfo['packet_amount'] > 0) {//结算流程

                    SettlementTransaction::afterCancelOrder($orderInfo['shop_id'], $orderInfo['order_no'],
                        $orderInfo['integral_amount'], $orderInfo['coupon_amount'], $orderInfo['activity_allowance'], $orderInfo['packet_amount']);

                }

                //取消店铺和平台优惠券后的提示信息
                $tipInfo = self::checkCancelCoupon($orderInfo['uid'], $orderNo, $orderInfo, $isSys, $eventId);

                return array_merge([
                    'status' => mOrder::STATUS_CLOSE
                ], $tipInfo);
            }
        } catch (\Exception $e) {
            tLog::order_OrderStatus_warning('取消订单异常', [
                'uid' => $uid,
                'order_no' => $orderNo,
                'cancel_type' => $isSys ? mOrder::CANCEL_TYPE_SYSTEM . '(自动取消)' : mOrder::CANCEL_TYPE_HANDLE . '(手动取消)',
                'order_status_to' => mOrder::STATUS_CLOSE,
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);

            throw $e;
        }

    }


    protected static function checkCancelCoupon($uid, $orderNo, $orderInfo, $isSys, $eventId = 0)
    {
        //取消店铺和平台优惠券的提示状态
        $cancelAmount = [
            'hhz' => 0,
            'shop' => 0
        ];

        //平台和店铺优惠券取消的操作
        if ($orderInfo['coupon_vid'] > 0) {

            //如果是最后一个取消的订单，那么则退还用户的优惠券
            $hhzCancel = clsOrder::lastCancelOrderWithCancelCoupon($uid, $orderInfo['order_parent_no']);

            //如果取消成功，那么则记录退款平台券的金额
            if ($hhzCancel) {

                $couponInfo = self::getCouponConfig($orderInfo['coupon_id']);

                $cancelAmount['hhz'] = $couponInfo['detract_amount'];


                //成功取消平台优惠券的使用
                Event::push(Event::ORDER_CANCEL_COUPON_SUCCESS, [
                    'uid' => $uid,
                    'order_no' => $orderNo,
                    'coupon_id' => $orderInfo['coupon_id'],
                    'coupon_vid' => $orderInfo['coupon_vid'],
                    'coupon_amount' => $couponInfo['detract_amount'],
                    'is_sys' => (int)$isSys,
                    'uniq_idx' => [
                        'order_no',
                        'event_tag'
                    ]
                ], $eventId);

            }

            tLog::order_OrderStatus_warning('取消订单时退还优惠券状态', [
                'uid' => $uid,
                'order_no' => $orderNo,
                'result' => $cancelAmount['hhz']
            ]);
        }

        if ($orderInfo['s_coupon_vid'] > 0) {

            $shopCancel = clsShopCoupon::cancelAShopCouponInOrder($uid, $orderInfo['shop_id'], $orderNo, $orderInfo['s_coupon_id'], $orderInfo['s_coupon_vid']);

            //如果取消成功，那么则记录退款平台券的金额
            if ($shopCancel) {
                $sCouponInfo = self::getCouponConfig($orderInfo['s_coupon_id']);

                $cancelAmount['shop'] = $sCouponInfo['detract_amount'];


                //成功取消商家优惠券的使用
                Event::push(Event::ORDER_CANCEL_S_COUPON_SUCCESS, [
                    'uid' => $uid,
                    'order_no' => $orderNo,
                    's_coupon_id' => $orderInfo['s_coupon_id'],
                    's_coupon_vid' => $orderInfo['s_coupon_vid'],
                    's_coupon_amount' => $sCouponInfo['detract_amount'],
                    'is_sys' => (int)$isSys,
                    'uniq_idx' => [
                        'order_no',
                        'event_tag'
                    ]
                ], $eventId);

            }

            tLog::order_OrderStatus_warning('取消订单时退还商家优惠券状态', [
                'uid' => $uid,
                'order_no' => $orderNo,
                's_coupon_vid' => $orderInfo['s_coupon_vid']
            ]);

        }

        if ($cancelAmount['hhz'] > 0 && $cancelAmount['shop'] > 0) {
            return [
                'tip_msg' => sprintf('%d元店铺优惠券和%d元平台优惠券已返还，请在我的优惠券中查看', $cancelAmount['shop'], $cancelAmount['hhz']),
            ];
        }

        if ($cancelAmount['hhz'] > 0) {
            return [
                'tip_msg' => sprintf('%d元平台优惠券已返还，请在我的优惠券中查看', $cancelAmount['hhz']),
            ];
        }


        if ($cancelAmount['shop'] > 0) {
            return [
                'tip_msg' => sprintf('%d元店铺优惠券已返还，请在我的优惠券中查看', $cancelAmount['shop']),
            ];
        }


        return [
            'tip_msg' => '',
        ];
    }

    public static function getCouponConfig($couponId)
    {
        $sCouponInfo = cCoupon::getConfig($couponId);

        return $sCouponInfo;
    }


    public static function modifyMessage($uid, $orderNo, $content)
    {
        $order = mOrder::getOrderInfo($orderNo, $uid);

        if ($order['status'] != mOrder::STATUS_NORMAL) {
            throw new \Exception('未付款订单可以修改留言');
        }

        mOrder::modifyMessage($uid, $orderNo, $content);
    }

    public static function getDetail($orderNo, $uid = 0)
    {

        $data = (new clsOrderDetail())->info($orderNo, $uid);

        return $data;


    }


    /**
     * 获取订单列表
     * @param $uid
     * @param $status
     * @param $page
     * @param $pageSize
     * @param $isCommented
     * @return array
     */
    public static function getList($uid, $status, $page, $pageSize, $isCommented)
    {
        list($fromSource, $orderType) = clsOrderList::detectFromSourceAndOrderType();

        $data = (new clsOrderList())->orderList($uid, $status, $page, $pageSize, $isCommented, $orderType, $fromSource);
        return $data;
    }

    /**
     * 确认收货
     * @param $orderNo
     * @param int $uid
     * @param bool $isSys
     * @return array
     * @throws \Exception
     */
    public static function confirmReceipt($uid = 0, $orderNo, $isSys = false, $isForce = false)
    {

        try {
            //判断是否父订单
            if (toolOrderNo::isParentNo($orderNo)) {
                throw new \Exception('父订单号不支持确认收货');
            }

            //判断是否有待处理中的退款申请
            $clsOrderRefund = new clsOrderRefund();
            $refundingStatus = $clsOrderRefund->checkOrderHasRefunding([$orderNo => mOrder::STATUS_SEND_OUT],
                'userReceipt');

            if ($isSys) {
                if ($refundingStatus == clsOrderRefund::REFUNDING_YES) {
                    throw new \Exception('该订单有待处理的退款申请，不可自动确认收货');
                }
            }

            //如果不是系统过来且不是强制，则返回提示
            if (!$isSys && !$isForce) {
                //如果是有处理中的退款申请，则将退款申请的状态设置为退款取消
                $code = 0;
                switch ($refundingStatus) {
                    case clsOrderRefund::REFUNDING_NO:

                        $code = clsErrorConst::ERROR_OREDER_USER_RECEIPT_PAUSETIP_REFUNDING_NO;

                        break;
                    case clsOrderRefund::REFUNDING_YES:

                        $code = clsErrorConst::ERROR_OREDER_USER_RECEIPT_PAUSETIP_REFUNDING_YES;

                        break;
                    case clsOrderRefund::REFUNDING_RIGHTS_IN:

                        $code = clsErrorConst::ERROR_OREDER_USER_RECEIPT_PAUSETIP_REFUNDING_RIGHTS_IN;

                        break;
                }

                $orderInfo = mOrder::getOrderInfo($orderNo);

                //部分发货，确认收货提示
                if ($orderInfo['status'] == mOrder::STATUS_SEND_PART_OUT) {
                    throw new \Exception(clsErrorConst::$errorDesc[clsErrorConst::ERROR_ORDER_STATUS_BY_PART_SEND]);
                }

                return [
                    'tip_code' => $code,
                    'tip_msg' => clsErrorConst::$errorDesc[$code]
                ];
            }


            $result = mOrder::action(function () use ($orderNo, $uid, $isSys, $isForce, &$orderInfo, $refundingStatus, $clsOrderRefund) {

                //获取订单信息
                $orderInfo = mOrder::getOrderInfoFromMaster($orderNo);


                //分担发货时的确认收货提示
                if ($orderInfo['status'] == mOrder::STATUS_SEND_PART_OUT) {
                    throw new \Exception('部分商品还没有发货，请收到全部商品后再操作。如有其他问题请联系客服。');
                }

                //判断订单状态  是不是已发货
                if (!mOrder::checkStatusCanConfirmReceipt($orderInfo['status'])) {
                    throw new \Exception('请核实订单状态');
                }

                //如果不是系统自动但是是强制，则需要做以下操作
                if (!$isSys && $isForce) {
                    if ($refundingStatus == clsOrderRefund::REFUNDING_RIGHTS_IN) {

                        //退款申请的单子取消
                        $clsOrderRefund->cancelOrderRefundList($orderNo, [
                            'cancel_rights',
                            'cancel_refund'
                        ]);
                    } elseif ($refundingStatus == clsOrderRefund::REFUNDING_YES) {

                        //退款申请的单子取消
                        $clsOrderRefund->cancelOrderRefundList($orderNo, ['cancel_refund']);

                    }
                }


                $data = [
                    'confirm_time' => date('Y-m-d H:i:s'),
                    'canrefund_stop_time' => date('Y-m-d H:i:s', time() + mOrder::MAX_WAIT_REFUND_TIME)
                ];
                $orderInfo['confirm_time'] = $data['confirm_time'];

                //判断是否为系统操作
                if (empty($uid) && $isSys) {
                    $data['status'] = mOrder::STATUS_SUCCESS;
                } else {
                    if ($orderInfo['uid'] != $uid) {
                        throw new \Exception('您没有此订单');
                    }
                    $data['status'] = mOrder::STATUS_SUCCESS;
                }

                //修改订单状态
                $result = mOrder::updateData($data, [
                    'order_no' => $orderNo,
                    'status' => mOrder::STATUS_SEND_OUT
                ]);
                if ($result == 0) {
                    throw new \Exception('状态修改失败');
                }


                //确认收货成功
                return true;
            });

            if ($result === true) {

                //确认收货成功后的事件
                Event::push(Event::ORDER_USER_CONFIRM_RECEIPT_SUCCESS, [
                    'uid' => $uid,
                    'order_no' => $orderNo,
                    'shop_id' => $orderInfo['shop_id'],
                    'is_sys' => (int)$isSys,
                    'uniq_idx' => [
                        'order_no',
                        'event_tag'
                    ]
                ]);


                return [
                    'status' => mOrder::V_STATUS_WAIT_COMMENT
                ];
            }
        } catch (\Exception $e) {
            tLog::order_OrderStatus_warning('确认收货异常', [
                'uid' => $uid,
                'order_no' => $orderNo,
                'order_status_to' => mOrder::STATUS_SUCCESS,
                'type' => $isSys ? '自动确认收货' : '手动确认收货',
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);
            throw $e;
        }

    }

    public static function addComment($order_no, $grade_num, $content, $currentUid)
    {
        if (!$order_no) {
            throw new \Exception('订单号不能为空');
        }
        $grade_num = abs($grade_num);
        if ($grade_num && $grade_num > 5) {
            throw new \Exception('分数等级超过最高5');
        }

        $orderInfo = mOrder::getOrderInfo($order_no);
        if ($orderInfo['status'] != mOrder::STATUS_SUCCESS || $orderInfo['is_commented'] != mOrder::COMMENT_STATUS_NO) {
            throw new \Exception('订单状态不允许评价');
        }
        if ($currentUid != $orderInfo['uid']) {
            throw new \Exception('订单不允许评价');
        }

        $result = ShopComments::addComment($order_no, $orderInfo['shop_id'], $orderInfo['uid'], $grade_num, $content);
        if ($result) {
            mOrder::updateData(['is_commented' => mOrder::COMMENT_STATUS_NORMAL], ['id' => $orderInfo['id']]);


            //添加评论的事件
            Event::push(Event::ORDER_USER_COMMENT_ORDER_SUCCESS, [
                'uid' => $orderInfo['uid'],
                'order_no' => $order_no,
                'shop_id' => $orderInfo['shop_id'],
                'comment' => $content,
                'uniq_idx' => [
                    'order_no',
                    'event_tag'
                ]
            ]);


        }

        return $result ? true : false;
    }

    public static function searchComments($params, $page = 1, $pagesize = 20)
    {
        $results = [
            'count' => 0,
            'list' => []
        ];
        $searchList = ShopComments::admSearch($params, $page, $pagesize);
        $results['count'] = $searchList['count'];
        $userIds = array_merge(array_column($searchList['list'], 'uid'),
            array_column($searchList['list'], 'shop_id'));

        $userInfos = User::getMultiUserInfos($userIds);
        foreach ($searchList['list'] as $list) {
            $results['list'][] = [
                'shop_id' => $list['shop_id'],
                'shop_nick' => isset($userInfos[$list['shop_id']]) ? $userInfos[$list['shop_id']]['nick'] : '',
                'order_no' => $list['order_no'],
                'uid' => $list['uid'],
                'uid_nick' => isset($userInfos[$list['uid']]) ? $userInfos[$list['uid']]['nick'] : '',
                'grade' => $list['grade'],
                'content' => $list['content'],
                'add_time' => $list['add_time'],
            ];
        }
        return $results;
    }

    public static function downloadComments($params)
    {
        $page = 0;
        $pagesize = 30;
        $file = "/tmp/" . date('YmdHis') . "orderComments.csv";
        $fp = fopen($file, "w");
        fputcsv($fp, [
            '商家',
            '订单',
            '买家',
            '评分',
            '用户留言',
            '评分时间'
        ]);
        try {
            do {
                $page++;
                $results = self::searchComments($params, $page, $pagesize);
                foreach ($results['list'] as $item) {
                    fputcsv($fp, [
                        $item['shop_nick'] . " ( " . $item['shop_id'] . " ) ",
                        $item['order_no'],
                        $item['uid_nick'] . " ( " . $item['uid'] . " ) ",
                        $item['grade'],
                        $item['content'],
                        $item['add_time']
                    ]);
                }
            } while ($results['count'] > $pagesize * $page);
        } catch (\Exception $e) {
            fclose($fp);
        }
        fclose($fp);
        return $file;
    }

    /**
     * 商家订单列表
     * @param $shopId
     * @param $params
     * @param $page
     * @param $pageSize
     * @return array
     */
    public static function mgtGetList($shopId, $params, $page, $pageSize)
    {
        if (is_null($page) || $page < 1) {
            $page = 1;
        }

        $params['shop_id'] = $shopId;
        $list = searchOrder::getList($params, searchOrder::SCENES_SELLER_ORDER, $params['order_type'], $page, $pageSize, 'order_no');
        $orderList = OrderList::sellerOrderList($list, $params['order_type']);
        return $orderList;


//        $limit = [
//            ($page - 1) * $pageSize,
//            $pageSize
//        ];
//        $params['shop_id'] = $shopId;
//        $orders = (new mgtOrderSearch($params, $limit))->orderList();
//        $data = [
//            'all_count' => $orders['all_count'],
//            'list' => $orders['list'],
//            'count' => $orders['count']
//        ];
//        return $data;
    }

    /**
     * 商家订单详情
     * @param $shopId
     * @param $orderNo
     * @return array
     * @throws \Exception
     */
    public static function mgtGetOrderInfo($shopId, $orderNo)
    {
        $result = (new mgtOrderDetail())->getInfo($shopId, $orderNo);
        return $result;
    }

    /**
     * 商家修改收货地址
     * @param $shopId
     * @param $orderNo
     * @param $consigneeCodes
     * @param $data
     * @return mixed
     * @throws \Exception
     */
    public static function mgtChangeAddress($shopId, $orderNo, $consigneeCodes, $data)
    {
        try {
            //判断是否父订单
            if (toolOrderNo::isParentNo($orderNo)) {
                throw new \Exception('父订单号不支持商家更该', 0);
            }

            $addressCodes = json_decode($consigneeCodes, true);
            if ($addressCodes) {
                $data['consignee_province'] = isset($addressCodes[0]) ? $addressCodes[0] : 0;
                $data['consignee_city'] = isset($addressCodes[1]) ? $addressCodes[1] : 0;
                $data['consignee_area'] = isset($addressCodes[2]) ? $addressCodes[2] : 0;
            }

            $result = mOrder::action(function () use ($shopId, $orderNo, &$data, &$orderInfo, &$row) {
                //获取订单信息
                $orderInfo = mOrder::getOrderByOrderNo($orderNo);

                if (!$orderInfo) {
                    throw new \Exception('订单信息不存在', 0);
                }

                //验证商家
                if ($orderInfo['shop_id'] != $shopId) {
                    throw new \Exception('该商家没有操作权限', 0);
                }

                if (!mOrder::checkStatusCanChangeAddress($orderInfo['status'])) {
                    throw new \Exception('订单已发货不能更该信息', 0);
                }

//                $province = tArea::locationId2Name($data['consignee_province']);
//                $city = tArea::locationId2Name($data['consignee_city']);
//                if ($city == '市辖区' || $city == '县') {
//                    $city = '';
//                }
//                if (empty($data['consignee_area'])) {
//                    $area = '';
//                } else {
//                    $area = tArea::locationId2Name($data['consignee_area']);
//                }
                $data['consignee_address'] = self::splicingConsignee($data['consignee_province'], $data['consignee_city'], $data['consignee_area'], $data['consignee_info_address']);
//                $data['consignee_address'] = $province . $city . $area . $data['consignee_info_address'];

                $row = mOrder::updateData($data, ['order_no' => $orderNo]);

            });

            if ($result !== false) {

                if (isset($orderInfo)) {

                    //商家修改收货地址
                    Event::push(Event::ORDER_MGT_CHANGE_ORDER_ADDRESS_SUCCESS, [
                        'shop_id' => $shopId,
                        'order_no' => $orderNo,
                        'realname' => $data['consignee_name'],
                        'mobile' => $data['consignee_phone'],
                        'province' => $data['consignee_province'],
                        'city' => $data['consignee_city'],
                        'address' => $data['consignee_info_address'],
                        'now_time' => date('Y-m-d H:i:s'),
                        'uniq_idx' => [
                            'order_no',
                            'event_tag',
                            'now_time'
                        ]
                    ]);


                    //交易记录日志
                    mOrderOperateLog::createLog($shopId, $orderNo, mOrderOperateLog::TRADE_TYPE_ORDER, [
                        'operate_user_type' => mOrderOperateLog::OPERATE_USERTYPE_MGT,
                        'operate_uid' => $shopId,
                        'operate_type' => mOrderOperateLog::OPERATE_TYPE_CHANGE_ADDRESS
                    ], '',
                        '修改前地址：' . $orderInfo['consignee_name'] . ' 、 ' . $orderInfo['consignee_phone'] . ' 、 ' . $orderInfo['consignee_address']);

                    //日志
                    sOperateLog::record(mOperateLog::TYPE_ORDER_MGT_CHANGE_ORDERS_STATUS, $shopId, $orderNo, [
                        'uid' => $orderInfo['uid'],
                        'consignee_name' => $orderInfo['consignee_name'],
                        'consignee_phone' => $orderInfo['consignee_phone'],
                        'consignee_province' => $orderInfo['consignee_province'],
                        'consignee_city' => $orderInfo['consignee_city'],
                        'consignee_area' => $orderInfo['consignee_area'],
                        'consignee_info_address' => $orderInfo['consignee_info_address'],
                        'consignee_address' => $orderInfo['consignee_address']
                    ], $data);
                }
            }

            return $row;

        } catch (\Exception $e) {
            tLog::order_OrderAddress_warning('修改地址异常', [
                'uid' => $orderInfo['uid'],
                'order_no' => $orderNo,
                'order_address_to' => json_encode($data),
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);
            throw $e;
        }

    }

    private static function splicingConsignee($provinceCode, $cityCode, $areaCode, $consigneeInfoAddress)
    {
        $province = tArea::locationId2Name($provinceCode);
        $city = tArea::locationId2Name($cityCode);
        if ($city == '市辖区' || $city == '县') {
            $city = '';
        }
        if (empty($areaCode)) {
            $area = '';
        } else {
            $area = tArea::locationId2Name($areaCode);
        }
        return $province . $city . $area . $consigneeInfoAddress;
    }

    /**
     * 商家变更运费
     * @param $shopId
     * @param $orderNo
     * @param $data
     * @return array
     * @throws \Exception
     */
    public static function mgtChangeShippingAmount($shopId, $orderNo, $data)
    {
        try {
            $parentData = [];
            $orderGoodsData = [];

            //判断是否父订单
            if (toolOrderNo::isParentNo($orderNo)) {
                throw new \Exception('父订单号不支持商家修改运费', 0);
            }

            //尝试关闭未支付的历史版本
            try {
                Pay::closeOrder($orderNo);
            } catch (\Exception $e) {
                throw new \Exception('订单已经支付，无法修改运费');
            }


            //开启事物
            $result = mOrder::action(function () use ($shopId, $orderNo, &$data, &$parentData, &$orderGoodsData, &$orderInfo, &$orderParentInfo, &$orderGoodsInfos) {
                //订单信息
                $orderInfo = mOrder::getOrderInfoFromMaster($orderNo);

                if (!$orderInfo) {
                    throw new \Exception('订单信息不存在', 0);
                }

                //验证商家
                if ($orderInfo['shop_id'] != $shopId) {
                    throw new \Exception('该商家没有操作权限', 0);
                }

                //验证是否待付款
                if (!mOrder::checkStatusCanPay($orderInfo['status'])) {
                    throw new \Exception('非待付款下不能修改运费', 0);
                }

                //验证运费是否为负数
                if ($data['shipping_amount'] < 0) {
                    throw new \Exception('运费不能为负数，上不封顶');
                }

                //实际支付金额
                $upData = [
                    'pay_ver[+]' => 1,
                    'shipping_amount' => $data['shipping_amount'],
                    'pay_amount' => $orderInfo['goods_amount'] + $data['shipping_amount'] - $orderInfo['coupon_amount'] - $orderInfo['integral_amount'] - $orderInfo['s_coupon_amount'],
                ];


                mOrder::updateData($upData, ['order_no' => $orderNo]);

                //运费差
                $disShipAmount = $data['shipping_amount'] - $orderInfo['shipping_amount'];

                //父订单信息
                $orderParentInfo = mOrderParent::getOrderParentInfoFromMaster($orderInfo['order_parent_no']);

                $parentData['shipping'] = $orderParentInfo['shipping'] + $disShipAmount;
                $parentData['pay_amount'] = $orderParentInfo['goods_amount'] + $orderParentInfo['shipping'] + $disShipAmount - $orderParentInfo['integral_amount'] - $orderParentInfo['coupon_amount'] - $orderParentInfo['sum_s_coupon_amount'];
                mOrderParent::updateData($parentData, ['order_parent_no' => $orderInfo['order_parent_no']]);
                if ($orderInfo['shipping_amount'] > 0) {//订单本来运费大于0，才能平摊到商品运费
                    //order goods
                    $orderGoodsList = mOrderGoods::getOrderGoodsFromMaster($orderNo);

                    $skuSort = [];
                    $orderGoodsInfos = [];
                    foreach ($orderGoodsList as $row) {
                        $skuSort[] = $row['shipping_amount'];
                        $orderGoodsInfos[] = [
                            'order_no' => $row['order_no'],
                            'sku_id' => $row['sku_id'],
                            'shipping_amount' => $row['shipping_amount']
                        ];
                    }
                    array_multisort($skuSort, SORT_ASC, $orderGoodsInfos);

                    $i = 0;
                    $count = count($orderGoodsInfos);
                    $total = 0;
                    foreach ($orderGoodsInfos as $row) {
                        if ($data['shipping_amount'] > 0) {
                            if ($i < $count - 1) {
                                $newShippingAmount = round(($row['shipping_amount'] / $orderInfo['shipping_amount']) * $data['shipping_amount'], 2);
                                $total = bcadd($total, $newShippingAmount, 2);
                            } else {
                                $newShippingAmount = bcsub($data['shipping_amount'], $total, 2);
                                $total = bcadd($total, $newShippingAmount, 2);
                            }
                        } else {
                            $newShippingAmount = 0;
                        }
                        $orderGoodsData[] = [
                            'sku_id' => $row['sku_id'],
                            'shipping' => $newShippingAmount,
                        ];
                        $result = mOrderGoods::updateData(['shipping_amount' => $newShippingAmount], ['order_no' => $orderNo, 'sku_id' => $row['sku_id']]);
                        if (!$result) {
                            return false;
                        }
                        $i++;
                    }

                    if (bccomp($data['shipping_amount'], $total, 2) != 0) {
                        throw new \Exception('更改运费计算错误', 0);
                    }
                }

            });

            if ($result !== false) {
                if (isset($orderInfo) && isset($orderParentInfo) && isset($orderGoodsInfos)) {

                    //商家修改运费事件
                    Event::push(Event::ORDER_MGT_CHANGE_SHIPPING_FEE_SUCCESS, [
                        'shop_id' => $shopId,
                        'order_no' => $orderNo,
                        'shipping_fee' => $data['shipping_amount'],
                        'before_change' => $orderInfo['shipping_amount'],
                        'now_time' => date('Y-m-d H:i:s'),
                        'uniq_idx' => [
                            'order_no',
                            'event_tag',
                            'now_time'
                        ]
                    ]);


                    //交易记录日志
                    mOrderOperateLog::createLog($shopId, $orderNo, mOrderOperateLog::TRADE_TYPE_ORDER, [
                        'operate_user_type' => mOrderOperateLog::OPERATE_USERTYPE_MGT,
                        'operate_uid' => $shopId,
                        'operate_type' => mOrderOperateLog::OPERATE_TYPE_CHANGE_SHIP_AMOUNT
                    ], '', '运费变更前：运费' . $orderInfo['shipping_amount'] . '￥ 实付金额：' . $orderInfo['pay_amount'] . '￥');

                    //日志
                    sOperateLog::record(mOperateLog::TYPE_ORDER_MGT_CHANGE_ORDERS_STATUS, $shopId, $orderNo, [
                        'uid' => $orderInfo['uid'],
                        'order' => [
                            'pay_amount' => $orderInfo['pay_amount'],
                            'shipping_amount' => $orderInfo['shipping_amount']
                        ],
                        'order_parent' => [
                            'pay_amount' => $orderParentInfo['pay_amount'],
                            'shipping' => $orderParentInfo['shipping']
                        ],
                        'order_goods' => $orderGoodsInfos
                    ], [
                        'uid' => $orderInfo['uid'],
                        'order' => [
                            'pay_amount' => $data['pay_amount'],
                            'shipping_amount' => $data['shipping_amount']
                        ],
                        'order_parent' => [
                            'pay_amount' => $parentData['pay_amount'],
                            'shipping' => $parentData['shipping']
                        ],
                        'order_goods' => $orderGoodsData,
                    ]);
                }

                return [
                    'order_amount' => Amount::format($orderInfo['goods_amount'] + $data['shipping_amount']),
                    'pay_amount' => Amount::format($data['pay_amount'])
                ];

            }

        } catch (\Exception $e) {

            tLog::order_OrderShipping_warning('更该运费异常', [
                'shop_id' => $shopId,
                'order_no' => $orderNo,
                'old_data' => json_encode([
                    'uid' => $orderInfo['uid'],
                    'order' => [
                        'pay_amount' => $orderInfo['pay_amount'],
                        'shipping_amount' => $orderInfo['shipping_amount']
                    ],
                    'order_parent' => [
                        'pay_amount' => $orderParentInfo['pay_amount'],
                        'shipping' => $orderParentInfo['shipping']
                    ],
                    'order_goods' => $orderGoodsInfos
                ], JSON_UNESCAPED_UNICODE),
                'new_data' => json_encode([
                    'uid' => $orderInfo['uid'],
                    'order' => [
                        'pay_amount' => $data['pay_amount'],
                        'shipping_amount' => $data['shipping_amount']
                    ],
                    'order_parent' => [
                        'pay_amount' => $parentData['pay_amount'],
                        'shipping' => $parentData['shipping']
                    ],
                    'order_goods' => $orderGoodsData,
                ], JSON_UNESCAPED_UNICODE),
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);

            throw $e;
        }
    }

    /**
     * 用户删除订单
     * @param $uid
     * @param $orderNo
     * @return mixed
     * @throws \Exception
     */
    public static function deleteOrder($uid, $orderNo)
    {
        try {

            if (toolOrderNo::isParentNo($orderNo)) {
                throw new \Exception('父订单号不支持用户删除', 0);
            }

            $result = mOrder::action(function () use ($uid, $orderNo, &$orderInfo, &$row) {

                //获取订单信息
                $orderInfo = mOrder::getOrderInfoFromMaster($orderNo);

                if ($orderInfo['uid'] != $uid) {
                    throw new \Exception('用户没有此订单操作权限');
                }

                if (!mOrder::checkStatusCanDelete($orderInfo['status'])) {
                    throw new \Exception('此状态下不能删除订单');
                }

                $row = mOrder::updateData(['status' => mOrder::STATUS_DEL], ['order_no' => $orderNo]);

            });

            if ($result !== false) {

                //交易记录日志
                mOrderOperateLog::createLog($orderInfo['shop_id'], $orderNo, mOrderOperateLog::TRADE_TYPE_ORDER, [
                    'operate_user_type' => mOrderOperateLog::OPERATE_USERTYPE_USER,
                    'operate_uid' => $uid,
                    'operate_type' => mOrderOperateLog::OPERATE_TYPE_DELETE_ORDER
                ], '', '用户删除订单');


                //用户删除订单的事件
                Event::push(Event::ORDER_USER_DELETE_ORDER_SUCCESS, [
                    'uid' => $uid,
                    'order_no' => $orderNo,
                    'shop_id' => $orderInfo['shop_id'],
                    'uniq_idx' => [
                        'order_no',
                        'event_tag'
                    ]
                ]);


                return $row;
            }

        } catch (\Exception $e) {
            tLog::order_OrderStatus_warning('用户删除订单异常', [
                'uid' => $orderInfo['uid'],
                'order_no' => $orderNo,
                'status' => $orderInfo['status'],
                'status_to' => mOrder::STATUS_DEL,
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);
        }
        throw $e;
    }

    /**
     * 商家发货订单下载
     * @param $shopId
     * @throws \Exception
     */
    public static function mgtDownList($shopId, $params, $type = 1)
    {
        (new mgtOrderExcel($shopId))->downList($params, 2);
    }

    /**
     * 用户延长收货
     * @param $uid
     * @param $orderNo
     * @return mixed
     * @throws \Exception
     */
    public static function prolongConfirm($uid, $orderNo)
    {
        try {

            if (toolOrderNo::isParentNo($orderNo)) {
                throw new \Exception('父订单号不支持用户删除', 0);
            }

            $result = mOrder::action(function () use ($uid, $orderNo, &$orderInfo, &$row) {

                $orderInfo = mOrder::getOrderInfoFromMaster($orderNo);

                if ($orderInfo['uid'] != $uid) {
                    throw new \Exception('您没有此订单操作权限');
                }

                if (!mOrder::checkStatusCanProlong($orderInfo['status'])) {
                    throw new \Exception('请核实订单状态');
                }
                //判断延长
                if (!mOrder::checkOrderCanProlong($orderInfo['prolong_time'])) {
                    throw new \Exception('您已延长收货');
                }

                $autoConfirmTime = strtotime($orderInfo['autoconfirm_time']);

                if (($autoConfirmTime - mOrder::MAX_WAIT_PROLONG_TIME) > time()) {
                    throw new \Exception('距离自动确认收货3天以内才能延长收货');
                }

                $row = mOrder::updateData(['prolong_time' => $orderInfo['maxprolong_time']], ['order_no' => $orderNo]);
            });

            if ($result !== false) {

                //交易记录日志
                mOrderOperateLog::createLog($orderInfo['shop_id'], $orderNo, mOrderOperateLog::TRADE_TYPE_ORDER, [
                    'operate_user_type' => mOrderOperateLog::OPERATE_USERTYPE_USER,
                    'operate_uid' => $uid,
                    'operate_type' => mOrderOperateLog::OPERATE_TYPE_PROLONG_ORDER
                ], '', '收货时间延长到' . $orderInfo['maxprolong_time']);

                //用户延长收货时间的事件
                Event::push(Event::ORDER_USER_PROLONG_TIME_ORDER_SUCCESS, [
                    'uid' => $uid,
                    'order_no' => $orderNo,
                    'shop_id' => $orderInfo['shop_id'],
                    'prolong_time' => $orderInfo['maxprolong_time'],
                    'uniq_idx' => [
                        'order_no',
                        'event_tag',
                        'prolong_time'
                    ]
                ]);


                return $row;

            }
        } catch (\Exception $e) {

            tLog::order_OrderStatus_warning('用户延长收货异常', [
                'uid' => $orderInfo['uid'],
                'order_no' => $orderNo,
                'autoconfirm_time' => $orderInfo['autoconfirm_time'],
                'autoconfirm_time_to' => $orderInfo['maxprolong_time'],
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);
            throw $e;
        }
    }

    /**
     * 订单信息
     * @param $orderNo
     * @param $skuId
     * @param int $shopId
     * @param int $uid
     * @return array
     * @throws \Exception
     */
    public static function mgtOrderMessage($orderNo, $skuId, $shopId)
    {
        $result = (new mOrderMessage($orderNo, $skuId))->getInfo($shopId);
        return $result;
    }

    /**
     * Excel文件上传
     * @param $shopId
     * @param $file
     * @return string
     * @throws \Exception
     */
    public static function mgtUpExcel($shopId, $file)
    {
        $file = (new mgtOrderExcel($shopId))->upLoad($file);
        $count = self::mgtBatchDelivery($shopId, $file);
        return $count;
    }

    /**
     * 批量发货
     * @param $shopId
     * @param $fileName
     * @return int
     * @throws \Exception
     */
    public static function mgtBatchDelivery($shopId, $file)
    {
        try {
            $orderExcel = new mgtOrderExcel($shopId);

            $readList = $orderExcel->readAndCheckByFormatExcel($file);

            //创建Excel日志

            $id = mOrderExcel::create(mOrderExcel::ORDER_BATCH_EXCEL_FALSE, $shopId, '正在发货中，请稍后刷新页面查看结果');

            //备份临时文件
            tLog::setExcelPath($file['tmp_name'], $id . '.xls');

            if (empty($readList)) {
                throw new \Exception('没有需要发货的订单');
            }

            $readListCount = count($readList);

            mOrderExcel::update(['all_count' => $readListCount,], ['id' => $id]);

            $courierList = sShopCourier::getCourierFileList();
            $courierList = array_column($courierList, null, 'courier_code');


            foreach ($readList as $expressNo => $infoList) {
                self::_async($expressNo, $infoList, $shopId, true, $id, $courierList);
            }

            return $readListCount;

        } catch (\Exception $e) {

            tLog::order_OrderStatus_warning('商家批量发货异常', [
                'shop_id' => $shopId,
                'format_data' => json_encode($readList),
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);

            throw $e;

        }
    }

    private static function _checkBatchDelivery($orderNo, $data, $shopId, $courierCode, $isMulti, $id, $courierList, $orderInfo, $courierCodeList, $info = [])
    {
        $whereSkuIds = [];
        //初始化变量
        $expressCompany = in_array($courierCode, $courierCodeList) ? $courierList[$courierCode]['courier_name'] : '';
        $expressNo = !empty($data['express_no']) ? $data['express_no'] : '';

        //初始化日志数据和excellog数据
        $excelLogData = [
            'shop_id' => $shopId,
            'excel_id' => $id,
            'order_no' => $orderNo,
            'express_company' => $expressCompany,
            'express_no' => $expressNo,
            'result' => 0
        ];

        $logData = [
            'shop_id' => $shopId,
            'orderNo' => $orderNo,
            'excel_id' => $id,
            'express_no' => $expressNo,
            'orderInfo' => $orderInfo,
            'courierCode' => $courierCode,
            'courierCodeList' => $courierCodeList
        ];


        //验证快递编码和快递单号
        if ((!in_array($courierCode, $courierCodeList)) || is_null($data['express_no'])) {
            if (empty($orderInfo)) {

                clsMgtOrderExcel::addError($id, '订单为空', array_merge($excelLogData, ['is_exist' => 0]), $logData);

                return true;
            } else {
                if ($shopId != $orderInfo['shop_id']) {

                    clsMgtOrderExcel::addError($id, '订单商家和当前商家不一样', $excelLogData, array_merge($logData, ['order_shop_id' => $orderInfo['shop_id']]));
                    return true;
                }

                clsMgtOrderExcel::addError($id, '快递编码或单号不正确', $excelLogData, $logData);

                return true;
            }
        }

        //验证是否是错误订单号
        if (empty($orderInfo)) {
            clsMgtOrderExcel::addError($id, '订单号不正确', array_merge($excelLogData, ['is_exist' => 0]), $logData);
            return true;
        }

        //验证商家订单号
        if ($orderInfo['shop_id'] != $shopId) {
            clsMgtOrderExcel::addError($id, '商家订单号不正确', array_merge($excelLogData, ['is_exist' => 0]), array_merge($logData, ['order_shop_id' => $orderInfo['shop_id']]));
            return true;
        }

        //验证订单号是否正在拼团
        $groupOrder = Group::getShopJoinOrder($shopId, '', '', $orderNo);
        if (!empty($groupOrder)) {
            clsMgtOrderExcel::addError($id, '拼团商品请在拼团成功后发货', array_merge($excelLogData, ['is_exist' => 0]), $logData);
            return true;
        }

        //验证订单号发货状态
        if (!mOrder::checkStatusCanShip($orderInfo['status'])) {
            clsMgtOrderExcel::addError($id, '订单发货状态不正确', array_merge($excelLogData, ['accept_name' => $orderInfo['consignee_name']]), array_merge($logData, ['order_status' => $orderInfo['status']]));
            return true;
        }

        if (!empty($info['sku_ids'])) {
            $whereSkuIds = ['sku_id' => $info['sku_ids']];
        }


        $clsOrderRefund = new clsOrderRefund();
        //判断是否退款中的订单
        $refundingStatus = $clsOrderRefund->checkOrderHasRefunding([$orderNo => mOrder::STATUS_WAIT_SEND], 'mgtShip', false, $whereSkuIds);

        if ($refundingStatus == $clsOrderRefund::REFUNDING_NO) {

            $result = self::mgtShipOrderByOrderNo($orderNo, $data, $shopId, $courierList[$courierCode]['courier_id'], $isMulti, $info['sku_ids']);

            if ($result) {

                $ret = mOrderExcel::action(function () use ($shopId, $id, $orderNo, $orderInfo, $data, $courierList, $courierCode, $expressCompany, $expressNo) {

                    $row = mOrderExcel::updateData(['expect_count[+]' => 1], ['id' => $id]);
                    if ($row == 0) {
                        throw new \Exception('修改成功条数失败');
                    }
                    $res = mOrderExcelLog::create($shopId, $id, $orderNo, $orderInfo['consignee_name'], [
                        'express_company' => $expressCompany,
                        'express_no' => $expressNo
                    ], mOrderExcelLog::ORDER_SHIP_SUCCESS);

                });
                if ($ret !== false) {
                    return true;
                }
            } else {
                clsMgtOrderExcel::addError($id, '发货失败', array_merge($excelLogData, ['accept_name' => $orderInfo['consignee_name']]), $logData);
                return true;
            }
        } else {
            clsMgtOrderExcel::addError($id, '有退款中的订单', array_merge($excelLogData, ['accept_name' => $orderInfo['consignee_name']]), array_merge($logData, ['sku_ids' => $info['sku_ids']]));
            return true;
        }
    }

    public static function _async_mgtBatchDelivery($expressNo, $infoList, $shopId, $isMulti, $id, $courierList)
    {

        $buildData = [];
        if (!empty($infoList)) {
            foreach ($infoList as $orderInfoKey => $info) {

                $orderInfo = explode('--', $orderInfoKey);

                $buildData[$orderInfo[0]]['sku_list'][] = $orderInfo[1];
                $buildData[$orderInfo[0]]['courier_code'] = $info['courier_code'];
            }
        }


        try {
            foreach ($buildData as $orderNo => $infos) {

                $orderInfo = mOrder::getOrderInfo($orderNo);

                $courierCodeList = array_column($courierList, 'courier_code');

                $info = [
                    'courier_code' => $infos['courier_code'],
                    'sku_ids' => trim(implode(',', $infos['sku_list']), ',')
                ];

                $res = self::_checkBatchDelivery($orderNo, ['express_no' => $expressNo], $shopId, $info['courier_code'], $isMulti, $id, $courierList, $orderInfo, $courierCodeList, $info);

                if ($res) {
                    $info = mOrderExcel::getOrderExcelInfoByIdFromMaster($id);
                    $count = $info['expect_count'] + $info['error_count'];
                    if ($count == $info['all_count']) {
                        mOrderExcel::updateData([
                            'message' => vsprintf("本次上传%s笔物流单号，成功发货%s笔，跳过%s笔", [
                                $info['all_count'],
                                $info['expect_count'],
                                $info['error_count']
                            ]),
                            'is_success' => mOrderExcel::ORDER_BATCH_EXCEL_SUCCESS
                        ], ['id' => $id]);
                    }
                }


            }

        } catch (\Exception $e) {
            tLog::order_orderstatus_warning('增加批量发货日志失败', [
                'shop_id' => $shopId,
                'order_no' => $orderNo,
                'accept_name' => $orderInfo['consignee_name'],
                'express_no' => $expressNo,
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);
        }
    }

    public static function admOrderMessage($orderNo, $skuId)
    {
        $result = (new clsAdmOrderMessage($orderNo, $skuId))->getInfo();
        return $result;
    }

    /**
     * 获取用户60天内购买过的商品id(已完成的订单)
     * @param $uid
     * @return array
     */
    public static function getSixtyUserOrderGoods($uid)
    {
        $where = [
            'uid' => $uid,
            'status' => mOrder::STATUS_SUCCESS,
            'addtime[>=]' => date('Y-m-d', strtotime('-59 days')),
        ];
        $orderNos = mOrder::getOrderInfoList($where, [], [], false, 'order_no');
        if ($orderNos) {
            $result = mOrderGoods::getUserOrderGoodsIds($uid, $orderNos);
            return $result;
        }
        return [];
    }

    /**
     * 管理后台订单列表
     * @param $params
     * @param $limit
     * @return array
     */
    public static function admGetOrderList($params, $limit)
    {
        $list = (new clsAdmOrderSearch($params, $limit))->orderList();

        return $list;
    }

    /**
     * 根据条件调用es 获取订单id
     * @param $params
     * @param $limit
     * @return array|mixed
     */
    public static function getOrderIds($params, $limit)
    {
        if (isset($params['order_no']) && $params['order_no']) {
            $orderNo = $params['order_no'];
            unset($params);
            $params['order_no'] = $orderNo;
        }

        if (isset($params['refund_no']) && $params['order_no']) {
            $refundNo = $params['refund_no'];
            unset($params);
            $params['refund_no'] = $refundNo;
        }

        //  如果有买家昵称或者商家名称的话，需要先根据名称获得id
        if (!empty($params['shop_name'])) {
            $results = AdmUserSearch::getUserIdsByFilter(['user_type' => [Member::AUTH_USER_BRAND], 'nick' => $params['shop_name']], 1);
            if ($results['rows']) {
                $params['shop_id'] = $results['rows'];
            }
            unset($params['shop_name']);
        }

        if (!empty($params['user_name'])) {
            $results = AdmUserSearch::getUserIdsByFilter(['user_type' => [Member::USER_COMMON], 'nick' => $params['user_name']], 1);
            if ($results['rows']) {
                $params['uid'] = $results['rows'];
            }
            unset($params['user_name']);
        }

        $orderIds = searchOrder::getList($params, searchOrder::SCENES_SHOP_ADMIN_ORDER, 1, $limit[0], $limit[1], 'order_no');
        return $orderIds;
    }

    public static function admGetOrderByOrderNos($orderNos)
    {
        $orderInfos = (new clsAdmOrderList())->getInfos($orderNos);
        return $orderInfos;
    }

    /**
     * 管理后台订单详情
     * @param $orderNo
     * @return array
     * @throws \Exception
     */
    public static function admGetDetail($orderNo)
    {
        $info = (new clsAdmOrderDetail())->getInfo($orderNo);
        return $info;
    }


    public static function admGetPringInfo($orderNo)
    {
        $info = (new clsAdmOrderDetail())->getPrintInfo($orderNo);
        return $info;
    }

    /**
     * 批量导出订单
     * @param $shopId
     * @param $params
     */
    public static function mgtBatchExport($shopId, $params)
    {
        ini_set('memory_limit', '-1');

        $params['shop_id'] = $shopId;
        $data = (new mgtOrderSearch($params, []))->orderList();
        (new mgtOrderExcel($shopId))->batchExport($data['list']);
    }

    /**
     * 订单状态统计
     * @param $uid
     * @return array
     */
    public static function getStatusCount($uid)
    {
        $statusCounts = [
            'wait_pay' => 0,
            'wait_send' => 0,
            'wait_receive' => 0,
            'wait_appraise' => 0
        ];

        list($fromSource, $orderType) = clsOrderList::detectFromSourceAndOrderType();

        $params = [
            'uid' => $uid,
            'order_type' => $orderType,
            'from_source' => $fromSource,
        ];
        $list = searchOrder::getList($params, searchOrder::SCENES_APP_ORDER_STATUS_COUNT, $params['order_type']);


        foreach ($statusCounts as $key => $count) {
            if (isset($list['aggregations'][$key])) {
                $statusCounts[$key] = $list['aggregations'][$key];
            }
        }

        return $statusCounts;
    }

    public static function mgtChangeExpress($shopId, $packageId = 0, $courierId = 0, $orderNo = '', $data = [])
    {
        try {

            $courierInfo = sShopCourier::getCourierFileInfo($courierId);


            $result = mOrder::action(function () use ($shopId, $orderNo, $packageId, $data, &$orderInfo, &$courierInfo) {

                $orderInfo = mOrder::getOrderInfoFromMaster($orderNo);

                if ($orderInfo['shop_id'] != $shopId) {
                    throw new \Exception('您没有操作此订单的权限哦');
                }

                if (!in_array($orderInfo['status'], [
                    mOrder::STATUS_SEND_PART_OUT,
                    mOrder::STATUS_SEND_OUT
                ])) {
                    throw new \Exception('请核实订单状态');
                }


                $data['express_company'] = $courierInfo['courier_name'];

                $ret = mOrderPackage::updatePackageExpressInfo($orderNo, $packageId, $courierInfo['courier_name'], $data['express_no']);


                {
                    //调用更新物流信息接口
                    $logistics = [];
                    $logistics['order_no'] = $orderNo;
                    $logistics['express_no'] = $data['express_no'];
                    $logistics['package_id'] = $packageId;
                    $logistics['uid'] = (int)$orderInfo['uid'];
                    $logistics['shop_id'] = (int)$shopId;
                    $logistics['addtime'] = date('Y-m-d H:i:s');
                    $logistics['edittime'] = date('Y-m-d H:i:s');
                    $logistics['courierbird_code'] = $courierInfo['courierbird_code'];
                    $logistics['trackingmore_code'] = $courierInfo['trackingmore_code'];

                    //订阅
                    $result = sLogistics::subscribe($logistics);
                }

                return true;
            });

            if ($result !== false) {

                if (isset($orderInfo) && !empty($orderInfo)) {

                    //如果是分单发货的订单，则需要查询出包裹的信息
                    if ($packageId > 0) {
                        $packageInfo = mOrderPackage::getPackageInfo($orderNo, $packageId);
                    }

                    $expressInfo = isset($packageInfo) ? $packageInfo : $orderInfo;
                    //交易记录日志
                    mOrderOperateLog::createLog($shopId, $orderNo, mOrderOperateLog::TRADE_TYPE_ORDER, [
                        'operate_user_type' => mOrderOperateLog::OPERATE_USERTYPE_MGT,
                        'operate_uid' => $shopId,
                        'operate_type' => mOrderOperateLog::OPERATE_TYPE_CHANGE_EXPRESS_ORDER
                    ], '', vsprintf('原物流信息：%s %s', [
                        $expressInfo['express_company'],
                        $expressInfo['express_no']
                    ]));


                    //日志
                    sOperateLog::record(mOperateLog::TYPE_ORDER_MGT_CHANGE_EXPRESS, $shopId, $orderNo, [
                        'uid' => $orderInfo['uid'],
                        'express_no' => $expressInfo['express_no'],
                        'express_company' => $expressInfo['express_company']
                    ], $data);

                    //商家修改物流信息的事件
                    Event::push(Event::ORDER_MGT_CHANGE_EXPRESS_INFO_SUCCESS, [
                        'shop_id' => $shopId,
                        'order_no' => $orderNo,
                        'package_id' => $packageId,
                        'express_company' => $expressInfo['express_company'],
                        'express_no' => $expressInfo['express_no'],
                        'now_time' => date('Y-m-d H:i:s'),
                        'uniq_idx' => [
                            'order_no',
                            'event_tag',
                            'now_time'
                        ]
                    ]);
                }
            }

        } catch (\Exception $e) {
            tLog::order_OrderChangeLogistics_warning('商家更新物流异常', [
                'shop_id' => $shopId,
                'package_id' => $packageId,
                'order_no' => $orderNo,
                'courierId' => $courierId,
                'data' => json_encode($data),
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);
            throw $e;
        }
    }

    public static function admGetConsignee($orderNo)
    {
        $consignee = (new clsAdmOrderDetail())->getConsignee($orderNo);
        return $consignee;
    }


    public static function mgtShipCheckTip($shopId, $orderNo)
    {
        try {

            //团购订单，成团中和失败不能发货
            $pintuan = mGroupJoinMember::getInfoByOrderNo($orderNo);
            if ($pintuan && $pintuan['status'] != 2) {
                return false;
            }

            //查询指定订单的退款单列表
            $refundList = mOrderRefund::select('*', [
                'shop_id' => $shopId,
                'order_no' => $orderNo
            ]);

            if (empty($refundList)) {
                return true;
            }

            //有拒绝的退款
            $rejectList = array_map(function ($v) {
                return $v['refund_order_no'];
            }, array_filter($refundList, function ($v) {
                if ($v['status'] == mOrderRefund::STATUS_REJECT && in_array($v['rights_status'],
                        [
                            0,
                            mOrderRefund::RIGHTS_STATUS_CANCEL
                        ])) {
                    return true;
                }
                return false;
            }));

            //有退款中或退款完成的列表
            $refundIngOrComplete = array_map(function ($v) {
                return $v['refund_order_no'];
            }, array_filter($refundList, function ($v) {
                if (in_array($v['status'], [
                    mOrderRefund::STATUS_WAIT_REFUND_GOODS,
                    mOrderRefund::STATUS_WAIT_CONFIRM_RECEIPT,
                    mOrderRefund::STATUS_REFUNDING,
                    mOrderRefund::STATUS_COMPLETE
                ])) {
                    return true;
                }
                return false;
            }));

            if (!empty($rejectList) && !empty($refundIngOrComplete)) {
                return '为避免用户拒收，请确认对方已同意发货，且包裹内不含已退款商品';
            }


            if (!empty($rejectList)) {
                $rejectLength = count($rejectList);

                if ($rejectLength > 1) {
                    $otherRefundList = array_filter($refundList, function ($v) use ($rejectList) {
                        if (!in_array($v['refund_order_no'], $rejectList)) {
                            if (!in_array($v['status'],
                                [
                                    mOrderRefund::STATUS_CANCEL,
                                    mOrderRefund::STATUS_RETURN_GOODS_CANCEL
                                ])) {
                                return true;
                            }
                        }

                        return false;
                    });

                }

                if (!empty($otherRefundList) || $rejectLength == 1) {
                    return '为避免用户拒收，请确认对方已同意发货';
                }

            }


            if (!empty($refundIngOrComplete)) {

                $refundIngOrCompleteLength = count($refundIngOrComplete);

                if ($refundIngOrCompleteLength > 1) {
                    $otherRefundList = array_filter($refundList, function ($v) use ($refundIngOrComplete) {
                        if (!in_array($v['refund_order_no'], $refundIngOrComplete)) {
                            if (!in_array($v['status'],
                                [
                                    mOrderRefund::STATUS_CANCEL,
                                    mOrderRefund::STATUS_RETURN_GOODS_CANCEL
                                ])) {
                                return true;
                            }
                        }

                        return false;
                    });
                }

                //如果商品中的全部商品都已同意退款  查询订单的总成功的退款金额
                $refundSum = mOrderRefund::get(['refund_sum' => Medoo::raw('SUM(refund_rmb+refund_shipping_amount)')], [
                    'order_no' => $orderNo,
                    'status' => [
                        mOrderRefund::STATUS_REFUNDING,
                        mOrderRefund::STATUS_COMPLETE
                    ]
                ]);

                //订单信息
                $orderInfo = mOrder::getOrderInfo($orderNo);

                //如果合计退款金额 == 支付金额
                if ($refundSum != null) {
                    if ($refundSum['refund_sum'] == $orderInfo['pay_amount']) {
                        return '';
                    }
                }

                if (!empty($otherRefundList) || $refundIngOrCompleteLength == 1) {
                    return '请确认包裹内不含已退款的商品';
                }
            }

            return '';

        } catch (\Exception $e) {
            tLog::order_OrderShip_warning('商家发货提示', [
                'shop_id' => $shopId,
                'order_no' => $orderNo,
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);

            throw $e;
        }
    }

    public static function mgtGetUpLog($shopId)
    {
        $list = mOrderExcel::getList([
            'shop_id' => $shopId,
            'LIMIT' => [
                0,
                10
            ],
            'ORDER' => ['addtime' => 'DESC']
        ]);
        return $list;
    }

    public static function mgtGetLogDetail($shopId, $id, $isJump)
    {
        if (empty($isJump)) {
            $list = mOrderExcelLog::getList([
                'shop_id' => $shopId,
                'excel_id' => $id,
                'ORDER' => ['addtime' => 'DESC']
            ]);
        } else {
            $list = mOrderExcelLog::getList([
                'shop_id' => $shopId,
                'excel_id' => $id,
                'result' => 0,
                'ORDER' => ['addtime' => 'DESC']
            ]);
        }

        $tip = mOrderExcel::getInfoById($id);

        return [
            'list' => $list,
            'tip' => $tip
        ];
    }

    public static function mgtGetStaticsSum($shopId)
    {

        $data = [];

        //待发货订单
        $data['wait_send_goods'] = mOrder::count([
            'shop_id' => $shopId,
            'status' => mOrder::STATUS_WAIT_SEND
        ]);

        //退款待审核
        $data['wait_apply_sum'] = mOrderRefund::count([
            'shop_id' => $shopId,
            'status' => mOrderRefund::STATUS_NORMAL
        ]);

        //待确认退货
        $data['wait_refund_goods'] = mOrderRefund::count([
            'shop_id' => $shopId,
            'status' => mOrderRefund::STATUS_WAIT_CONFIRM_RECEIPT
        ]);

        return $data;
    }

    /**
     * 获取用户已购买的商品(点图标签使用)
     * @param $uid 用户uid
     * @param $page 分页
     * @param int $pageSize 分页大小
     * @return array
     */
    public static function getBoughtGoodsForImgTag($uid, $page, $pageSize = 20)
    {
        $cacheData = UserBoughtGoodsCache::getUserBoughtGoods($uid, $page, $pageSize);
        $goodsIds = [];
        if ($cacheData['count'] > 0) {
            $goodsIds = $cacheData['list'];
        }
        $goodsList = GoodsDetail::formatBasicInfos($goodsIds);
        $brandIds = [];
        foreach ($goodsList as $goodsId => $goodsInfo) {
            if ($goodsInfo['brand_info']) {
                $brandIds[] = $goodsInfo['brand_info']['id'];
            }
        }
        $commonTags = Brand::getBrandCommenTagByBIds($brandIds);
        $list = [];
        foreach ($goodsIds as $goodsId) {
            if ($goodsList[$goodsId]) {
                $goodInfo = $goodsList[$goodsId];
                $category = (isset($goodInfo['category']) && $goodInfo['category']) ? array_pop($goodInfo['category']) : [];
                $brandName = '';
                if (isset($commonTags[$goodInfo['brand_info']['id']]) && $commonTags[$goodInfo['brand_info']['id']] && $goodInfo['brand_info']) {
                    $brandName = $goodInfo['brand_info']['name'];
                };
                $list[$goodsId] = [
                    'type' => SearchAddTag::GOODS_TAG_TPYE,
                    'goods_info' => [
                        'goods_id' => $goodsId,
                        'title' => $goodInfo['title'],
                        'brand_name' => $brandName,
                        'spec_img_url' => $goodInfo['spec_img_url'],
                        'spec_img_thumb_url' => $goodInfo['spec_img_thumb_url'],
                        'category_name' => ($category && isset($category['cate_name'])) ? $category['cate_name'] : '',
                    ],
                ];
            }
        }
        $count = $list ? $cacheData['count'] : 0;
        return [
            'count' => $count,
            'list' => $list ? array_values($list) : [],
            'is_over' => ($page * $pageSize) >= $count ? 1 : 0
        ];
    }

    /**
     * 获取订单的备注信息
     * @param $orderNos
     * @return array ['order_no1' => [
     *                        'seller_message' => '',
     *                        'hhz_message' => []
     *              ],'order_no2' => [
     *                        'seller_message' => '',
     *                          'hhz_message' => []
     *              ]]
     */
    public static function OrderRemarks($orderNos)
    {
        $orderRemarks = mOrderRemark::getRemarksByOrderNo($orderNos);
        $orderRemarkInfo = [
        ];
        $confirmInfos = self::hhzOrderConfirmContent($orderNos);
        $adminUsers = AdminUser::getAdminList(array_column($orderRemarks, 'action_uid'));
        foreach ($orderRemarks as $orderRemark) {
            if ($orderRemark['remark_type'] == mOrderRemark::REMARK_TYPE_BUSINESS) {
                if (!isset($orderRemarkInfo[$orderRemark['order_no']]['seller_message'])) {
                    $orderRemarkInfo[$orderRemark['order_no']]['seller_message'] = $orderRemark['content'];
                    $orderRemarkInfo[$orderRemark['order_no']]['seller_message_time'] = $orderRemark['add_time'];
                }
                $orderRemarkInfo[$orderRemark['order_no']]['seller_messages'][] = [
                    'order_no' => $orderRemark['order_no'],
                    'add_time' => $orderRemark['add_time'],
                    'content' => $orderRemark['content']
                ];
            } else if ($orderRemark['remark_type'] == mOrderRemark::REMARK_TYPE_HHZ) {
                $orderRemarkInfo[$orderRemark['order_no']]['hhz_message'][] = [
                    'order_no' => $orderRemark['order_no'],
                    'add_time' => $orderRemark['add_time'],
                    'hhz_remark_type' => $orderRemark['hhz_remark_type'],
                    'hhz_remark_type_des' => mOrderRemark::HHZ_REMARK_MAPS[$orderRemark['hhz_remark_type']],
                    'admin_uid_des' => !empty($orderRemark['action_uid']) ? $adminUsers[$orderRemark['action_uid']]['name'] : '',
                    'content' => in_array($orderRemark['hhz_remark_type'], [mOrderRemark::HHZ_REMARK_TYPE_APPEND, mOrderRemark::HHZ_REMARK_TYPE_API_APPEND]) ?
                        $orderRemark['content'] :
                        (isset($confirmInfos[$orderRemark['content']]) ? $confirmInfos[$orderRemark['content']] : '')
                ];
            }
        }

        return $orderRemarkInfo;
    }

    private static function hhzOrderConfirmContent($orderNOs)
    {
        $orderConfirms = mHhzOrderConfirm::getInfo($orderNOs);
        $confirmInfos = [];
        foreach ($orderConfirms as $orderConfirm) {
            $confirmInfo = '';
            if ($orderConfirm['is_cover_consignee']) {
                $confirmInfo .= '「已根据客户要求修改了订单的收货信息，';
            }
            if ($orderConfirm['goods_title']) {
                $confirmInfo .= mHhzOrderConfirm::CONFIRM_FIELD_MAPS['goods_title'] . " : ";
                $confirmInfo .= $orderConfirm['goods_title'] . " <br/>";
            }
            $confirmInfo .= mHhzOrderConfirm::CONFIRM_FIELD_MAPS['consignee_time'] . " : ";
            $confirmInfo .= $orderConfirm['consignee_time'] == "0000-00-00 00:00:00" ? '尽快 ' : $orderConfirm['consignee_time'] . "  <br/>";
//            $confirmInfo .= mHhzOrderConfirm::CONFIRM_FIELD_MAPS['consignee_address'] . " : ";
//            $confirmInfo .= $orderConfirm['consignee_address'] . " " . $orderConfirm['consignee'] . " " . $orderConfirm['consignee_phone'] . " <br/>";
            $confirmInfo .= mHhzOrderConfirm::CONFIRM_FIELD_MAPS['is_inter_community'] . " : ";
            $confirmInfo .= $orderConfirm['is_inter_community'] ? '是 ' : '否 ';
            $confirmInfo .= mHhzOrderConfirm::CONFIRM_FIELD_MAPS['is_has_elevator'] . " : ";
            $confirmInfo .= $orderConfirm['is_has_elevator'] ? '是 ' : '否 ';
            $confirmInfo .= mHhzOrderConfirm::CONFIRM_FIELD_MAPS['upstair_cost'] . " : ";
            $confirmInfo .= $orderConfirm['upstair_cost'] == '0.00' ? '无 ' : $orderConfirm['upstair_cost'] . "";
            $confirmInfos[$orderConfirm['id']] = $confirmInfo;
        }
        return $confirmInfos;
    }

    public static function mgtSaveRemark($shopId, $orderNo, $remark)
    {
        try {
            $orderInfo = mOrder::getOrderInfoFromMaster($orderNo);

            if ($orderInfo['shop_id'] != $shopId) {
                throw new \Exception('您没有操作此订单的权限哦');
            }
            $rest = mOrderRemark::action(function () use ($shopId, $orderNo, $remark) {

//                mOrderRemark::updateRemark($orderNo, mOrderRemark::REMARK_TYPE_BUSINESS, $shopId, [
//                    'remark_status' => mOrderRemark::REMARK_STATUS_DEL
//                ]);
                return mOrderRemark::addRemark($orderNo, mOrderRemark::REMARK_TYPE_BUSINESS, $shopId, [
                    'content' => $remark
                ]);
            });

            if ($rest > 0) {

                //商家成功对订单进行备注
                Event::push(Event::ORDER_MGT_SAVE_ORDER_REMARK_SUCCESS, [
                    'shop_id' => $shopId,
                    'order_no' => $orderNo,
                    'remark' => $remark,
                    'now_time' => date('Y-m-d H:i:s'),
                    'uniq_idx' => [
                        'order_no',
                        'event_tag',
                        'now_time'
                    ]
                ]);

            }


        } catch (\Exception $e) {
            tLog::error('商家修改备注出错', [
                'shop_id' => $shopId,
                'order_no' => $orderNo,
                'remark' => $remark,
                'e_msg' => $e->getMessage(),
            ]);

            throw $e;
        }
        return $rest;
    }

    public static function admSaveOrderRemark($adminUid, $orderNo, $postData, $hhzRemarkType = mOrderRemark::HHZ_REMARK_TYPE_COMFIRM)
    {
        if ($hhzRemarkType == mOrderRemark::HHZ_REMARK_TYPE_COMFIRM) {
            if (!isset($postData['consignee_time_type']) && !$postData['consignee_time']) {
                throw new \Exception('请检查送货时间项');
            }
            if (!($postData['consignee_address'] &&
                $postData['consignee_phone'] &&
                $postData['consignee_province'] &&
                $postData['consignee_city'] &&
                $postData['consignee_area'] &&
                $postData['consignee'] &&
                (isset($postData['is_inter_community'])) &&
                isset($postData['is_has_elevator']))) {
                throw new \Exception('请检查信息是否填写完全');
            }
            OrderRemark::action(function () use ($adminUid, $orderNo, $postData) {
                try {
                    $orderConsignee = [];
                    $orderConsignee['consignee_info_address'] = $postData['consignee_address'];
                    $orderConsignee['consignee_address'] = self::splicingConsignee($postData['consignee_province'], $postData['consignee_city'], $postData['consignee_area'], $postData['consignee_address']);
                    $orderConsignee['consignee_phone'] = $postData['consignee_phone'];
                    $orderConsignee['consignee_province'] = $postData['consignee_province'];
                    $orderConsignee['consignee_city'] = $postData['consignee_city'];
                    $orderConsignee['consignee_area'] = $postData['consignee_area'];
                    $orderConsignee['consignee_name'] = $postData['consignee'];
                    $orderInfo = mOrder::getOrderByOrderNo($orderNo);
                    $rowCount = mOrder::updateData($orderConsignee, ['order_no' => $orderNo]);

                    $id = mHhzOrderConfirm::addConfirmInfo($orderNo, [
                        'goods_title' => $postData['goods_title'],
                        'consignee_time' => $postData['consignee_time'],
                        'consignee_address' => $orderConsignee['consignee_address'],
                        'consignee_phone' => $postData['consignee_phone'],
                        'consignee' => $postData['consignee'],
                        'is_cover_consignee' => $rowCount ? 1 : 0,
                        'is_inter_community' => $postData['is_inter_community'],
                        'is_has_elevator' => $postData['is_has_elevator'],
                        'upstair_cost' => $postData['upstair_cost'] ?: '0.00'
                    ]);
                    if ($rowCount) {//添加订单交易记录
                        $text_content = '修改前地址：' . $orderInfo['consignee_name'] . " " . $orderInfo['consignee_phone'] . " " . $orderInfo['consignee_address'];
                        OrderOperateLog::createLog($orderInfo['shop_id'], $orderNo, OrderOperateLog::TRADE_TYPE_ORDER, [
                            'operate_user_type' => mOrderOperateLog::OPERATE_USERTYPE_SYS,
                            'operate_uid' => $adminUid,
                            'operate_type' => mOrderOperateLog::OPERATE_TYPE_HHZ_CHANGE_ADDRESS
                        ], '', $text_content, '');
                    }
                    /*             if (OrderRemark::get('*', [
                                     'order_no' => $orderNo,
                                     'remark_type' => OrderRemark::REMARK_TYPE_HHZ,
                                     'hhz_remark_type' => OrderRemark::HHZ_REMARK_TYPE_COMFIRM,
                                     'remark_status' => OrderRemark::REMARK_STATUS_NORMAL
                                 ])) {
                                     throw new \Exception('该订单核实信息已存在');
                                 }*/
                    if (!$id) {
                        throw new \Exception('系统错误');
                    }
                    return OrderRemark::addRemark($orderNo, OrderRemark::REMARK_TYPE_HHZ, $adminUid, [
                        'hhz_remark_type' => OrderRemark::HHZ_REMARK_TYPE_COMFIRM,
                        'content' => $id
                    ]);

                } catch (\Exception $e) {
                    throw $e;
                }
            });
        } else if (in_array($hhzRemarkType, [mOrderRemark::HHZ_REMARK_TYPE_APPEND, mOrderRemark::HHZ_REMARK_TYPE_API_APPEND])) {
            if (!trim($postData['content'])) {
                throw new \Exception('请检查信息是否填写完全');
            }
            OrderRemark::addRemark($orderNo, OrderRemark::REMARK_TYPE_HHZ, $adminUid, [
                'hhz_remark_type' => $hhzRemarkType,
                'content' => $postData['content']
            ]);


            //管理员追加订单备注
            Event::push(Event::ORDER_ADM_SAVE_ORDER_REMARK_SUCCESS, [
                'admin_uid' => $adminUid,
                'order_no' => $orderNo,
                'remark' => $postData['content'],
                'now_time' => date('Y-m-d H:i:s'),
                'uniq_idx' => [
                    'order_no',
                    'event_tag',
                    'now_time'
                ]
            ]);
        }

    }

    public static function mgtGetCanShipSkuIds($shopId, $orderNo)
    {
        $result = clsMgtOrderInfo::getCanShipSkuIds($shopId, $orderNo);

        return $result;
    }

    public static function getPackageList($orderNo, $withExpress = false, $uid = 0)
    {
        $data = [];
        $packageList = clsOrderPackage::getOrderPackageList($orderNo, true, $withExpress, $uid);
        if ($packageList) {
            $data['package_list'] = $packageList;
        } else {
            $order = mOrder::getOrderInfo($orderNo, $uid);
            $data['package_list'][] = [
                'package_id' => "0",
                'package_title' => "包裹1",
                "express_company" => $order['express_company'],
                "express_no" => $order['express_no'],
                "sku_list" => []
            ];
        }
        return $data;
    }

    public static function getCancelReasonList()
    {
        $reasonList = mOrder::$cancelReasonDesc;

        $list = [];

        foreach ($reasonList as $key => $value) {
            $list[] = [
                'reason_id' => $key,
                'reason' => $value
            ];
        }

        return $list;
    }

    public static function admSaveConsigneeTime($orderNo, $adminUid, $skuId, $consigneeTime = '')
    {
        $upData = ['reserve_receipt_time' => $consigneeTime];

        mOrderGoods::update($upData, [
            'order_no' => $orderNo,
            'sku_id' => $skuId
        ]);

        $orderInfo = mOrder::getOrderInfo($orderNo);

        //增加订单记录日志
        $result = mOrderOperateLog::createLog($orderInfo['shop_id'], $orderInfo['order_no'], mOrderOperateLog::TRADE_TYPE_ORDER, [
            'operate_type' => mOrderOperateLog::OPERATE_TYPE_ADMIN_CHANGE_CONSIGNEE_TIME_SUCCESS,
            'operate_user_type' => mOrderOperateLog::OPERATE_USERTYPE_SYS,
            'operate_uid' => $adminUid,
        ], '', sprintf("skuId=%d 的期望送货时间：%s", $skuId, $consigneeTime));

        // var_dump(mOrderMatching::sqlLogs());exit;

    }

    //自提确认接口
    public static function mgtSelfConfirm($shopId, $orderNo)
    {
        $isSelfShop = mShopBasicInfo::checkIsSelfOperated($shopId);

        if (!$isSelfShop) {
            return false;
        }

        $orderInfo = mOrder::getOrderInfo($orderNo);

        $packageInfo = mOrderPackage::getFirstPackageInfo($orderNo);

        $expressData = [
            'express_no' => $packageInfo['express_no'],
        ];

        $skuIdList = mOrderGoods::getSkuIds($orderNo);

        $result = clsMgtOrder::shipOrder($orderNo, $expressData, $shopId, mShopCourier::SELF_LIFTING_ID, false, implode(',', $skuIdList));

        self::confirmReceipt($orderInfo['uid'], $orderNo, false, true);


        return $result;

    }


    public static function getPaySuccInfo($uid, $orderPNo, $addressId = 0)
    {

        $data = clsOrderInfo::paySuccInfo($uid, $orderPNo, $addressId);

        return $data;


    }

    public static function matchingSave($uid, $orderPNo, $addressId, $addressTipInfo, $receiptTimeList)
    {
        clsOrderInfo::matchingSave($uid, $orderPNo, $addressId, $addressTipInfo, $receiptTimeList);
    }
}